#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define NUM 1024
#define SIZE 32

char argArr[NUM];
char* g_arg[SIZE];


int main(int argc,char* argv[],char* env[])
{
    // shell的原理：父进程进行命令获取，命令解析和回收等待子进程  子进程执行命令
    while(true)
    {
        // 1,打印命令行提示---[yx@VM-12-12-centos three20220922]$
        printf("[root@---------#]");
        fflush(stdout); // 刷新缓冲区
        
        // 2,获取命令
        memset(argArr,'\0',sizeof argArr); // 将字符数组元素都置成\0

        fgets(argArr,NUM,stdin); // 通过fgets将缓冲区的命令读取到argArr字符数组中

        argArr[strlen(argArr)-1]='\0'; // 将字符数组中的最后一个\n置成\0
        
       //printf("echo:%s\n",argArr);
       // 3,分割命令
       g_arg[0]=strtok(argArr," ");
       int index=1;
       while(g_arg[index++]=strtok(NULL," "));

       //4,内置命令的处理
       
       if(strcmp(g_arg[0],"cd")==0)
       {
            
           chdir(g_arg[1]);
           continue;
       }

       //5,创建子进程执行命令
       pid_t id=fork();

       if(id==0) // 子进程执行的代码段
       {
           execvpe(g_arg[0],g_arg,env); // 进程替换
       }

       int status=0;
       pid_t ret=waitpid(id,&status,0); // 父进程等待回收子进程
       if(ret>0)
       {
           printf("等待回车成功：退出码：%d 退出信号：%d\n",WEXITSTATUS(status),status&0x7F);
       }

    }


    return 0;
}
